package algorithm.view.maze;

import algorithm.view.common.AlgoHelpler;

import java.awt.*;
import java.util.LinkedList;
import java.util.Stack;
/**
 * @author bingo
 * @Description
 * @Date 2018/4/29
 */
public class AlgoVisualizer {

    private AlgoFrame algoFrame;

    private   String FILE_PATH="";

    private MazeData mazeData = null;

    private  int blockSize = 9;

    /**上下左右方向辅助数组*/
    private int[][]  d = {
                          {-1,0},
                          {0,1},
                          {1,0},
                          {0,-1}
                        };

    public AlgoVisualizer(String path) {
        this.FILE_PATH = path;
        mazeData =   new MazeData(FILE_PATH);
        int senceWeight = mazeData.getM()*blockSize;
        int senceHeight = mazeData.getL()*blockSize;
        System.out.println("窗体高度："+senceHeight+"窗体宽度:"+senceWeight);
        EventQueue.invokeLater(()-> {
           algoFrame = new AlgoFrame("welcome", senceWeight, senceHeight);
           new Thread(()->{
                  run();
           }).start();

        });
    }

    public void run(){
        setData();
        go(mazeData.getEntranceX(),mazeData.getEntranceY());
        //go2();
        //go3();
        setData();
        }
    public void setData(){
        algoFrame.render(mazeData);
        AlgoHelpler.pause(5);

    }
    /**递归方式走迷宫**/
    public  boolean  go(int x,int y){
        mazeData.visited[x][y] =true;
        mazeData.path[x][y] = true;
        setData();
        if(x==mazeData.getExitX()&&y==mazeData.getExitY()){
          return true;
        }
        System.out.println("入口坐标x="+x+"y="+y);
        for(int i=0;i<4;i++){
            int newX = x+d[i][0];
            int newY = y+d[i][1];
            System.out.println("newX："+newX+"  newY："+newY);
            if(mazeData.inArea(newX,newY)&&mazeData.visited[newX][newY]==false&&
                    (mazeData.getData()[newX][newY]==MazeData.RODE)){
               if(go(newX,newY)){
                   return  true;
               }

            }
        }
        mazeData.path[x][y] = false;

        return  false;
    }


    /**非递归方式走迷宫*/
     public void  go2(){

         Stack<Position> stack = new Stack();
         Position entrance = new Position(mazeData.getEntranceX(),mazeData.getEntranceY());
         stack.push(entrance);
         mazeData.visited[entrance.getX()][entrance.getY()]=true;
         while(!stack.isEmpty()){
             Position curPosition = stack.pop();
            int x = curPosition.getX();
            int y = curPosition.getY();
            mazeData.path[x][y] = true;
            setData();
             if(x==mazeData.getExitX()&&y==mazeData.getExitY()){
                 findPath(curPosition);
                 break;
             }
             System.out.println("入口坐标x="+x+"y="+y);
            for(int i=0;i<4;i++){
                int newX = x+d[i][0];
                int newY = y+d[i][1];
                System.out.println("newX："+newX+"  newY："+newY);
                if(mazeData.inArea(newX,newY)&&mazeData.visited[newX][newY]==false&&
                        (mazeData.getData()[newX][newY]==MazeData.RODE)){
                  stack.push(new Position(newX,newY,curPosition));
                  mazeData.visited[newX][newY] =true;
                }
               /* else  {
                    if(mazeData.inArea(newX,newY)){
                        mazeData.path[newX][newY]=false;
                    }

                }*/
            }

        }

     }
     /**广度优先遍历走迷宫*/
    public void  go3(){
        LinkedList<Position> queue = new LinkedList();
        Position entrance = new Position(mazeData.getEntranceX(),mazeData.getEntranceY());
        queue.addLast(entrance);
        mazeData.visited[entrance.getX()][entrance.getY()]=true;
        while(queue.size()!=0){
            Position curPosition = queue.pop();
            int x = curPosition.getX();
            int y = curPosition.getY();
            mazeData.path[x][y] = true;
            setData();
            if(x==mazeData.getExitX()&&y==mazeData.getExitY()){
                findPath(curPosition);
                break;
            }
            System.out.println("入口坐标x="+x+"y="+y);
            for(int i=0;i<4;i++){
                int newX = x+d[i][0];
                int newY = y+d[i][1];
                System.out.println("newX："+newX+"  newY："+newY);
                if(mazeData.inArea(newX,newY)&&mazeData.visited[newX][newY]==false&&
                        (mazeData.getData()[newX][newY]==MazeData.RODE)){
                    queue.addLast(new Position(newX,newY,curPosition));
                    mazeData.visited[newX][newY] =true;
                }
            }

        }

    }

    private void findPath(Position curPosition) {
        while(curPosition!=null){
            mazeData.result[curPosition.getX()][curPosition.getY()]  = true;
            curPosition = curPosition.getPrev();
            setData();
        }
    }


}
